﻿namespace Atomic.Plugins
{
    using System;
    using System.Collections.Generic;

    using Atomic.Plugins.Files;

    /// <summary>
    /// 插件管理器。
    /// </summary>
    public static class PluginManager
    {
        /// <summary>
        /// 插件管理器。
        /// </summary>
        private static IPluginManager _pluginManager = null;

        /// <summary>
        /// 当前插件管理器。
        /// </summary>
        public static IPluginManager Current
        {
            get
            {
                return _pluginManager;
            }
        }

        /// <summary>
        /// 初始化插件管理器。
        /// </summary>
        /// <param name="pluginInitializer">插件初始化程序。</param>
        public static void Initialize(IPluginInitializer pluginInitializer)
        {
            var factory = new PluginManagerFactory(pluginInitializer);

            Create(factory);
        }

        /// <summary>
        /// 初始化插件管理器。
        /// </summary>
        /// <param name="factory">插件管理器工厂。</param>
        public static void Initialize(IPluginManagerFactory factory)
        {
            Create(factory);
        }

        /// <summary>
        /// 创建插件管理器。
        /// </summary>
        /// <param name="factory">插件管理器工厂。</param>
        private static void Create(IPluginManagerFactory factory)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory", "插件管理器工厂 factory 不可以是空的。");
            }

            if (factory != null)
            {
                _pluginManager = factory.Build();
            }
        }
    }

    /// <summary>
    /// 插件管理器工厂接口。
    /// </summary>
    public interface IPluginManagerFactory
    {
        /// <summary>
        /// 创建程序集加载器。
        /// </summary>
        void CreateAssemblyLoader();

        /// <summary>
        /// 创建虚拟路径提供程序。
        /// </summary>
        void CreateVirtualPathProvider();

        /// <summary>
        /// 创建程序集搜索目录。
        /// </summary>
        void CreateAssemblyProbingFolder();

        /// <summary>
        /// 创建插件配置信息获取程序。
        /// </summary>
        void CreateManifestManager();

        /// <summary>
        /// 创建插件获取程序。
        /// </summary>
        void CreatePluginHarvester();

        /// <summary>
        /// 创建插件加载器。
        /// </summary>
        void CreatePluginLoader();

        /// <summary>
        /// 创建插件目录对象。
        /// </summary>
        void CreatePluginFolder();

        /// <summary>
        /// 生成插件管理器。
        /// </summary>
        /// <returns>插件管理器。</returns>
        IPluginManager Build();
    }

    /// <summary>
    /// 插件管理器工厂。
    /// </summary>
    public class PluginManagerFactory : IPluginManagerFactory
    {
        /// <summary>
        /// 插件初始化程序。
        /// </summary>
        private IPluginInitializer _pluginInitializer = null;

        /// <summary>
        /// 程序集加载器。
        /// </summary>
        private IAssemblyLoader _assemblyLoader = null;

        /// <summary>
        /// 虚拟路径提供程序。
        /// </summary>
        private IVirtualPathProvider _virtualPathProvider = null;

        /// <summary>
        /// 程序集搜索目录。
        /// </summary>
        private IAssemblyProbingFolder _assemblyProbingFolder = null;

        /// <summary>
        /// 插件配置信息获取程序。
        /// </summary>
        private IManifestManager _manifestManager = null;

        /// <summary>
        /// 插件获取程序。
        /// </summary>
        private IPluginHarvester _pluginHarvester = null;

        /// <summary>
        /// 插件加载器。
        /// </summary>
        private IPluginLoader _pluginLoader = null;

        /// <summary>
        /// 插件目录。
        /// </summary>
        private IEnumerable<IPluginFolder> _pluginFolders = null;

        /// <summary>
        /// 插件管理器。
        /// </summary>
        private IPluginManager _pluginManager = null;

        /// <summary>
        /// 初始化插件管理器工厂。
        /// </summary>
        /// <param name="pluginInitializer">插件初始化程序。</param>
        public PluginManagerFactory(IPluginInitializer pluginInitializer)
        {
            if (pluginInitializer == null)
            {
                throw new ArgumentNullException("pluginInitializer", "插件初始化程序 pluginInitializer 不可以是空的。");
            }

            this._pluginInitializer = pluginInitializer;
        }

        /// <summary>
        /// 创建程序集加载器。
        /// </summary>
        public void CreateAssemblyLoader()
        {
            this._assemblyLoader = new DefaultAssemblyLoader();
        }

        /// <summary>
        /// 创建虚拟路径提供程序。
        /// </summary>
        public void CreateVirtualPathProvider()
        {
            this._virtualPathProvider = new DefaultVirtualPathProvider();
        }

        /// <summary>
        /// 创建程序集搜索目录。
        /// </summary>
        public void CreateAssemblyProbingFolder()
        {
            if (this._assemblyLoader == null)
            {
                this.CreateAssemblyLoader();
            }

            this._assemblyProbingFolder = new DefaultAssemblyProbingFolder(this._assemblyLoader);
        }

        /// <summary>
        /// 创建插件配置信息获取程序。
        /// </summary>
        public void CreateManifestManager()
        {
            if (this._virtualPathProvider == null)
            {
                this.CreateVirtualPathProvider();
            }

            this._manifestManager = new DefaultManifestManager(this._virtualPathProvider);
        }

        /// <summary>
        /// 创建插件获取程序。
        /// </summary>
        public void CreatePluginHarvester()
        {
            if (this._virtualPathProvider == null)
            {
                this.CreateVirtualPathProvider();
            }

            if (this._manifestManager == null)
            {
                this.CreateManifestManager();
            }

            this._pluginHarvester = new PluginHarvester(this._virtualPathProvider, this._manifestManager);
        }

        /// <summary>
        /// 创建插件加载器。
        /// </summary>
        public void CreatePluginLoader()
        {
            if (this._virtualPathProvider == null)
            {
                this.CreateVirtualPathProvider();
            }

            if (this._assemblyProbingFolder == null)
            {
                this.CreateAssemblyProbingFolder();
            }

            this._pluginLoader = new DefaultPluginLoader(this._pluginInitializer, this._virtualPathProvider, this._assemblyProbingFolder);
        }

        /// <summary>
        /// 创建插件目录对象。
        /// </summary>
        public void CreatePluginFolder()
        {
            IPluginFolder coreFolder = new CoreFolder(this._pluginHarvester);
            IPluginFolder pluginFolder = new PluginFolder(this._pluginHarvester);

            this._pluginFolders = new List<IPluginFolder>() { coreFolder, pluginFolder };
        }

        /// <summary>
        /// 生成插件管理器。
        /// </summary>
        /// <returns>插件管理器。</returns>
        public IPluginManager Build()
        {
            this.CreateAssemblyLoader();
            this.CreateVirtualPathProvider();
            this.CreateAssemblyProbingFolder();
            this.CreateManifestManager();
            this.CreatePluginHarvester();
            this.CreatePluginLoader();
            this.CreatePluginFolder();

            this._pluginManager = new DefaultPluginManager(this._pluginLoader, this._pluginFolders);

            return this._pluginManager;
        }
    }
}